home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / UNIX Cracking / MacCracSource.sit / MacCrac.source / Source / crack-lib.c < prev    next >
Text File  |  1995-01-20  |  14KB  |  751 lines

  1. /*
  2.  * This program is copyright Alec Muffett 1991 except for some portions of
  3.  * code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus Sparry
  4.  * and Alec Muffett.  The author(s) disclaims all responsibility or liability
  5.  * with respect to it's usage or its effect upon hardware or computer
  6.  * systems, and maintain copyright as set out in the "LICENCE" document which
  7.  * accompanies distributions of Crack v4.0 and upwards.
  8.  */
  9.  
  10. #include "crack.h"
  11. #include <string.h>
  12. #include <strings.h>
  13.  
  14. #define RULE_NOOP    ':'
  15. #define RULE_PREPEND    '^'
  16. #define RULE_APPEND    '$'
  17. #define RULE_REVERSE    'r'
  18. #define RULE_UPPERCASE    'u'
  19. #define RULE_LOWERCASE    'l'
  20. #define RULE_PLURALISE    'p'
  21. #define RULE_CAPITALISE    'c'
  22. #define RULE_DUPLICATE    'd'
  23. #define RULE_REFLECT    'f'
  24. #define RULE_SUBSTITUTE    's'
  25. #define RULE_MATCH    '/'
  26. #define RULE_NOT    '!'
  27. #define RULE_LT        '<'
  28. #define RULE_GT        '>'
  29. #define RULE_EXTRACT    'x'
  30. #define RULE_OVERSTRIKE    'o'
  31. #define RULE_INSERT    'i'
  32. #define RULE_EQUALS    '='
  33. #define RULE_PURGE    '@'
  34. #define RULE_CLASS    '?'    /* class rule? socialist ethic in cracker? */
  35.  
  36. extern void Log();
  37.  
  38. void
  39. Trim (string)        /* remove trailing whitespace from a string */
  40.     register char *string;
  41. {
  42.     register char *ptr;
  43.  
  44.     for (ptr = string; *ptr; ptr++);
  45.     while ((--ptr >= string) && isspace (*ptr));
  46.     *(++ptr) = '\0';
  47. }
  48.  
  49. char *
  50. Clone (string)
  51.     char *string;
  52. {
  53.     register char *retval;
  54.  
  55.     retval = (char *) malloc (strlen (string) + 1);
  56.     if (retval)
  57.     {
  58.     strcpy (retval, string);
  59.     }
  60.     return (retval);
  61. }
  62.  
  63. int
  64. Suffix (word, suffix)
  65.     char *word;
  66.     char *suffix;
  67. {
  68.     register int i;
  69.     register int j;
  70.  
  71.     i = strlen (word);
  72.     j = strlen (suffix);
  73.  
  74.     if (i > j)
  75.     {
  76.     return (STRCMP ((word + i - j), suffix));
  77.     } else
  78.     {
  79.     return (-1);
  80.     }
  81. }
  82.  
  83. char *
  84. Reverse (str)            /* return a pointer to a reversal */
  85.     register char *str;
  86. {
  87.     register int i;
  88.     register int j;
  89.     static char area[STRINGSIZE];
  90.  
  91.     j = i = strlen (str);
  92.     while (*str)
  93.     {
  94.     area[--i] = *str++;
  95.     }
  96.     area[j] = '\0';
  97.     return (area);
  98. }
  99.  
  100. char *
  101. Uppercase (str)            /* return a pointer to an uppercase */
  102.     register char *str;
  103. {
  104.     register char *ptr;
  105.     static char area[STRINGSIZE];
  106.  
  107.     ptr = area;
  108.     while (*str)
  109.     {
  110.     *(ptr++) = CRACK_TOUPPER (*str);
  111.     str++;
  112.     }
  113.     *ptr = '\0';
  114.  
  115.     return (area);
  116. }
  117.  
  118. char *
  119. Lowercase (str)            /* return a pointer to an lowercase */
  120.     register char *str;
  121. {
  122.     register char *ptr;
  123.     static char area[STRINGSIZE];
  124.  
  125.     ptr = area;
  126.     while (*str)
  127.     {
  128.     *(ptr++) = CRACK_TOLOWER (*str);
  129.     str++;
  130.     }
  131.     *ptr = '\0';
  132.  
  133.     return (area);
  134. }
  135.  
  136. char *
  137. Capitalise (str)        /* return a pointer to an capitalised */
  138.     register char *str;
  139. {
  140.     register char *ptr;
  141.     static char area[STRINGSIZE];
  142.  
  143.     ptr = area;
  144.  
  145.     while (*str)
  146.     {
  147.     *(ptr++) = CRACK_TOLOWER (*str);
  148.     str++;
  149.     }
  150.  
  151.     *ptr = '\0';
  152.     area[0] = CRACK_TOUPPER (area[0]);
  153.     return (area);
  154. }
  155.  
  156. char *
  157. Pluralise (string)        /* returns a pointer to a plural */
  158.     register char *string;
  159. {
  160.     register int length;
  161.     static char area[STRINGSIZE];
  162.  
  163.     length = strlen (string);
  164.     strcpy (area, string);
  165.  
  166.     if (!Suffix (string, "ch") ||
  167.     !Suffix (string, "ex") ||
  168.     !Suffix (string, "ix") ||
  169.     !Suffix (string, "sh") ||
  170.     !Suffix (string, "ss"))
  171.     {
  172.     /* bench -> benches */
  173.     strcat (area, "es");
  174.     } else if (length > 2 && string[length - 1] == 'y')
  175.     {
  176.     if (strchr ("aeiou", string[length - 2]))
  177.     {
  178.         /* alloy -> alloys */
  179.         strcat (area, "s");
  180.     } else
  181.     {
  182.         /* gully -> gullies */
  183.         strcpy (area + length - 1, "ies");
  184.     }
  185.     } else if (string[length - 1] == 's')
  186.     {
  187.     /* bias -> biases */
  188.     strcat (area, "es");
  189.     } else
  190.     {
  191.     /* catchall */
  192.     strcat (area, "s");
  193.     }
  194.  
  195.     return (area);
  196. }
  197.  
  198. char *
  199. Substitute (string, old, gnew)    /* returns pointer to a swapped about copy */
  200.     register char *string;
  201.     register char old;
  202.     register char gnew;
  203. {
  204.     register char *ptr;
  205.     static char area[STRINGSIZE];
  206.  
  207.     ptr = area;
  208.     while (*string)
  209.     {
  210.     *(ptr++) = (*string == old ? gnew : *string);
  211.     string++;
  212.     }
  213.     *ptr = '\0';
  214.     return (area);
  215. }
  216.  
  217. char *
  218. Purge (string, target)        /* returns pointer to a purged copy */
  219.     register char *string;
  220.     register char target;
  221. {
  222.     register char *ptr;
  223.     static char area[STRINGSIZE];
  224.  
  225.     ptr = area;
  226.     while (*string)
  227.     {
  228.     if (*string != target)
  229.     {
  230.         *(ptr++) = *string;
  231.     }
  232.     string++;
  233.     }
  234.     *ptr = '\0';
  235.     return (area);
  236. }
  237. /* -------- CHARACTER CLASSES START HERE -------- */
  238.  
  239. /*
  240.  * this function takes two inputs, a class identifier and a character, and
  241.  * returns non-null if the given character is a member of the class, based
  242.  * upon restrictions set out below
  243.  */
  244.  
  245. int
  246. MatchClass (class, input)
  247.     register char class;
  248.     register char input;
  249. {
  250.     register char c;
  251.     register int retval;
  252.  
  253.     retval = 0;
  254.  
  255.     switch (class)
  256.     {
  257.     /* ESCAPE */
  258.  
  259.     case '?':            /* ?? -> ? */
  260.     if (input == '?')
  261.     {
  262.         retval = 1;
  263.     }
  264.     break;
  265.  
  266.     /* ILLOGICAL GROUPINGS (ie: not in ctype.h) */
  267.  
  268.     case 'V':
  269.     case 'v':            /* vowels */
  270.     c = CRACK_TOLOWER (input);
  271.     if (strchr ("aeiou", c))
  272.     {
  273.         retval = 1;
  274.     }
  275.     break;
  276.  
  277.     case 'C':
  278.     case 'c':            /* consonants */
  279.     c = CRACK_TOLOWER (input);
  280.     if (strchr ("bcdfghjklmnpqrstvwxyz", c))
  281.     {
  282.         retval = 1;
  283.     }
  284.     break;
  285.  
  286.     case 'W':
  287.     case 'w':            /* whitespace */
  288.     if (strchr ("\t ", input))
  289.     {
  290.         retval = 1;
  291.     }
  292.     break;
  293.  
  294.     case 'P':
  295.     case 'p':            /* punctuation */
  296.     if (strchr (".`,:;'!?\"", input))
  297.     {
  298.         retval = 1;
  299.     }
  300.     break;
  301.  
  302.     case 'S':
  303.     case 's':            /* symbols */
  304.     if (strchr ("$%%^&*()-_+=|\\[]{}#@/~", input))
  305.     {
  306.         retval = 1;
  307.     }
  308.     break;
  309.  
  310.     /* LOGICAL GROUPINGS */
  311.  
  312.     case 'L':
  313.     case 'l':            /* lowercase */
  314.     if (islower (input))
  315.     {
  316.         retval = 1;
  317.     }
  318.     break;
  319.  
  320.     case 'U':
  321.     case 'u':            /* uppercase */
  322.     if (isupper (input))
  323.     {
  324.         retval = 1;
  325.     }
  326.     break;
  327.  
  328.     case 'A':
  329.     case 'a':            /* alphabetic */
  330.     if (isalpha (input))
  331.     {
  332.         retval = 1;
  333.     }
  334.     break;
  335.  
  336.     case 'X':
  337.     case 'x':            /* alphanumeric */
  338.     if (isalnum (input))
  339.     {
  340.         retval = 1;
  341.     }
  342.     break;
  343.  
  344.     case 'D':
  345.     case 'd':            /* digits */
  346.     if (isdigit (input))
  347.     {
  348.         retval = 1;
  349.     }
  350.     break;
  351.  
  352.     default:
  353.     Log ("MatchClass: unknown class %c\n", class);
  354.     return (0);
  355.     break;
  356.     }
  357.  
  358.     if (isupper (class))
  359.     {
  360.     return (!retval);
  361.     }
  362.     return (retval);
  363. }
  364.  
  365. char *
  366. PolyStrchr (string, class)
  367.     register char *string;
  368.     register char class;
  369. {
  370.     while (*string)
  371.     {
  372.     if (MatchClass (class, *string))
  373.     {
  374.         return (string);
  375.     }
  376.     string++;
  377.     }
  378.     return ((char *) 0);
  379. }
  380.  
  381. char *
  382. PolySubst (string, class, new)    /* returns pointer to a swapped about copy */
  383.     register char *string;
  384.     register char class;
  385.     register char new;
  386. {
  387.     register char *ptr;
  388.     static char area[STRINGSIZE];
  389.  
  390.     ptr = area;
  391.     while (*string)
  392.     {
  393.     *(ptr++) = (MatchClass (class, *string) ? new : *string);
  394.     string++;
  395.     }
  396.     *ptr = '\0';
  397.     return (area);
  398. }
  399.  
  400. char *
  401. PolyPurge (string, class)    /* returns pointer to a purged copy */
  402.     register char *string;
  403.     register char class;
  404. {
  405.     register char *ptr;
  406.     static char area[STRINGSIZE];
  407.  
  408.     ptr = area;
  409.     while (*string)
  410.     {
  411.     if (!MatchClass (class, *string))
  412.     {
  413.         *(ptr++) = *string;
  414.     }
  415.     string++;
  416.     }
  417.     *ptr = '\0';
  418.     return (area);
  419. }
  420. /* -------- BACK TO NORMALITY -------- */
  421.  
  422. int
  423. Char2Int (character)
  424.     char character;
  425. {
  426.     if (isdigit (character))
  427.     {
  428.     return (character - '0');
  429.     } else if (islower (character))
  430.     {
  431.     return (character - 'a' + 10);
  432.     } else if (isupper (character))
  433.     {
  434.     return (character - 'A' + 10);
  435.     }
  436.     return (-1);
  437. }
  438.  
  439. char *
  440. Mangle (input, control)        /* returns a pointer to a controlled Mangle */
  441.     char *input;
  442.     char *control;
  443. {
  444.     int limit;
  445.     register char *ptr;
  446.     static char area[STRINGSIZE];
  447.     char area2[STRINGSIZE];
  448.  
  449.     area[0] = '\0';
  450.     strcpy (area, input);
  451.  
  452.     for (ptr = control; *ptr; ptr++)
  453.     {
  454.     switch (*ptr)
  455.     {
  456.     case RULE_NOOP:
  457.         break;
  458.     case RULE_REVERSE:
  459.         strcpy (area, Reverse (area));
  460.         break;
  461.     case RULE_UPPERCASE:
  462.         strcpy (area, Uppercase (area));
  463.         break;
  464.     case RULE_LOWERCASE:
  465.         strcpy (area, Lowercase (area));
  466.         break;
  467.     case RULE_CAPITALISE:
  468.         strcpy (area, Capitalise (area));
  469.         break;
  470.     case RULE_PLURALISE:
  471.         strcpy (area, Pluralise (area));
  472.         break;
  473.     case RULE_REFLECT:
  474.         strcat (area, Reverse (area));
  475.         break;
  476.     case RULE_DUPLICATE:
  477.         strcpy (area2, area);
  478.         strcat (area, area2);
  479.         break;
  480.     case RULE_GT:
  481.         if (!ptr[1])
  482.         {
  483.         Log ("Mangle: '>' missing argument in '%s'\n", control);
  484.         return ((char *) 0);
  485.         } else
  486.         {
  487.         limit = Char2Int (*(++ptr));
  488.         if (limit < 0)
  489.         {
  490.             Log ("Mangle: '>' weird argument in '%s'\n", control);
  491.             return ((char *) 0);
  492.         }
  493.         if (strlen (area) <= limit)
  494.         {
  495.             return ((char *) 0);
  496.         }
  497.         }
  498.         break;
  499.     case RULE_LT:
  500.         if (!ptr[1])
  501.         {
  502.         Log ("Mangle: '<' missing argument in '%s'\n", control);
  503.         return ((char *) 0);
  504.         } else
  505.         {
  506.         limit = Char2Int (*(++ptr));
  507.         if (limit < 0)
  508.         {
  509.             Log ("Mangle: '<' weird argument in '%s'\n", control);
  510.             return ((char *) 0);
  511.         }
  512.         if (strlen (area) >= limit)
  513.         {
  514.             return ((char *) 0);
  515.         }
  516.         }
  517.         break;
  518.     case RULE_PREPEND:
  519.         if (!ptr[1])
  520.         {
  521.         Log ("Mangle: prepend missing argument in '%s'\n", control);
  522.         return ((char *) 0);
  523.         } else
  524.         {
  525.         area2[0] = *(++ptr);
  526.         strcpy (area2 + 1, area);
  527.         strcpy (area, area2);
  528.         }
  529.         break;
  530.     case RULE_APPEND:
  531.         if (!ptr[1])
  532.         {
  533.         Log ("Mangle: append missing argument in '%s'\n", control);
  534.         return ((char *) 0);
  535.         } else
  536.         {
  537.         register char *string;
  538.  
  539.         string = area;
  540.         while (*(string++));
  541.         string[-1] = *(++ptr);
  542.         *string = '\0';
  543.         }
  544.         break;
  545.     case RULE_EXTRACT:
  546.         if (!ptr[1] || !ptr[2])
  547.         {
  548.         Log ("Mangle: extract missing argument in '%s'\n", control);
  549.         return ((char *) 0);
  550.         } else
  551.         {
  552.         register int i;
  553.         int start;
  554.         int length;
  555.  
  556.         start = Char2Int (*(++ptr));
  557.         length = Char2Int (*(++ptr));
  558.         if (start < 0 || length < 0)
  559.         {
  560.             Log ("Mangle: extract: weird argument in '%s'\n", control);
  561.             return ((char *) 0);
  562.         }
  563.         strcpy (area2, area);
  564.         for (i = 0; length-- && area2[start + i]; i++)
  565.         {
  566.             area[i] = area2[start + i];
  567.         }
  568.         /* cant use strncpy() - no trailing NUL */
  569.         area[i] = '\0';
  570.         }
  571.         break;
  572.     case RULE_OVERSTRIKE:
  573.         if (!ptr[1] || !ptr[2])
  574.         {
  575.         Log ("Mangle: overstrike missing argument in '%s'\n", control);
  576.         return ((char *) 0);
  577.         } else
  578.         {
  579.         register int i;
  580.  
  581.         i = Char2Int (*(++ptr));
  582.         if (i < 0)
  583.         {
  584.             Log ("Mangle: overstrike weird argument in '%s'\n",
  585.              control);
  586.             return ((char *) 0);
  587.         } else
  588.         {
  589.             ++ptr;
  590.             if (area[i])
  591.             {
  592.             area[i] = *ptr;
  593.             }
  594.         }
  595.         }
  596.         break;
  597.     case RULE_INSERT:
  598.         if (!ptr[1] || !ptr[2])
  599.         {
  600.         Log ("Mangle: insert missing argument in '%s'\n", control);
  601.         return ((char *) 0);
  602.         } else
  603.         {
  604.         register int i;
  605.         register char *p1;
  606.         register char *p2;
  607.  
  608.         i = Char2Int (*(++ptr));
  609.         if (i < 0)
  610.         {
  611.             Log ("Mangle: insert weird argument in '%s'\n",
  612.              control);
  613.             return ((char *) 0);
  614.         }
  615.         p1 = area;
  616.         p2 = area2;
  617.         while (i && *p1)
  618.         {
  619.             i--;
  620.             *(p2++) = *(p1++);
  621.         }
  622.         *(p2++) = *(++ptr);
  623.         strcpy (p2, p1);
  624.         strcpy (area, area2);
  625.         }
  626.         break;
  627.         /* THE FOLLOWING RULES REQUIRE CLASS MATCHING */
  628.  
  629.     case RULE_PURGE:    /* @x or @?c */
  630.         if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  631.         {
  632.         Log ("Mangle: delete missing arguments in '%s'\n", control);
  633.         return ((char *) 0);
  634.         } else if (ptr[1] != RULE_CLASS)
  635.         {
  636.         strcpy (area, Purge (area, *(++ptr)));
  637.         } else
  638.         {
  639.         strcpy (area, PolyPurge (area, ptr[2]));
  640.         ptr += 2;
  641.         }
  642.         break;
  643.     case RULE_SUBSTITUTE:    /* sxy || s?cy */
  644.         if (!ptr[1] || !ptr[2] || (ptr[1] == RULE_CLASS && !ptr[3]))
  645.         {
  646.         Log ("Mangle: subst missing argument in '%s'\n", control);
  647.         return ((char *) 0);
  648.         } else if (ptr[1] != RULE_CLASS)
  649.         {
  650.         strcpy (area, Substitute (area, ptr[1], ptr[2]));
  651.         ptr += 2;
  652.         } else
  653.         {
  654.         strcpy (area, PolySubst (area, ptr[2], ptr[3]));
  655.         ptr += 3;
  656.         }
  657.         break;
  658.     case RULE_MATCH:    /* /x || /?c */
  659.         if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  660.         {
  661.         Log ("Mangle: '/' missing argument in '%s'\n", control);
  662.         return ((char *) 0);
  663.         } else if (ptr[1] != RULE_CLASS)
  664.         {
  665.         if (!strchr (area, *(++ptr)))
  666.         {
  667.             return ((char *) 0);
  668.         }
  669.         } else
  670.         {
  671.         if (!PolyStrchr (area, ptr[2]))
  672.         {
  673.             return ((char *) 0);
  674.         }
  675.         ptr += 2;
  676.         }
  677.         break;
  678.     case RULE_NOT:        /* !x || !?c */
  679.         if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
  680.         {
  681.         Log ("Mangle: '!' missing argument in '%s'\n", control);
  682.         return ((char *) 0);
  683.         } else if (ptr[1] != RULE_CLASS)
  684.         {
  685.         if (strchr (area, *(++ptr)))
  686.         {
  687.             return ((char *) 0);
  688.         }
  689.         } else
  690.         {
  691.         if (PolyStrchr (area, ptr[2]))
  692.         {
  693.             return ((char *) 0);
  694.         }
  695.         ptr += 2;
  696.         }
  697.         break;
  698.  
  699.         /*
  700.          * alternative use for a boomerang, number 1: a standard throwing
  701.          * boomerang is an ideal thing to use to tuck the sheets under
  702.          * the mattress when making your bed.  The streamlined shape of
  703.          * the boomerang allows it to slip easily 'twixt mattress and
  704.          * bedframe, and it's curve makes it very easy to hook sheets
  705.          * into the gap.
  706.          */
  707.  
  708.     case RULE_EQUALS:    /* =nx || =n?c */
  709.         if (!ptr[1] || !ptr[2] || (ptr[2] == RULE_CLASS && !ptr[3]))
  710.         {
  711.         Log ("Mangle: '=' missing argument in '%s'\n", control);
  712.         return ((char *) 0);
  713.         } else
  714.         {
  715.         register int i;
  716.  
  717.         if ((i = Char2Int (ptr[1])) < 0)
  718.         {
  719.             Log ("Mangle: '=' weird argument in '%s'\n", control);
  720.             return ((char *) 0);
  721.         }
  722.         if (ptr[2] != RULE_CLASS)
  723.         {
  724.             ptr += 2;
  725.             if (area[i] != *ptr)
  726.             {
  727.             return ((char *) 0);
  728.             }
  729.         } else
  730.         {
  731.             ptr += 3;
  732.             if (!MatchClass (*ptr, area[i]))
  733.             {
  734.             return ((char *) 0);
  735.             }
  736.         }
  737.         }
  738.         break;
  739.     default:
  740.         Log ("Mangle: unknown command %c in %s\n", *ptr, control);
  741.         return ((char *) 0);
  742.         break;
  743.     }
  744.     }
  745.     if (!area[0])        /* have we deweted de poor widdle fing away? */
  746.     {
  747.     return ((char *) 0);
  748.     }
  749.     return (area);
  750. }
  751.